{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 1.基于scikit learn中的KNeighborsClassifier类的水果分类",
   "id": "6594b722a00a5ef4"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 1.1导入相应包",
   "id": "a5c11d2d4e42fc27"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:41.329008Z",
     "start_time": "2024-12-04T14:32:40.805031Z"
    }
   },
   "cell_type": "code",
   "source": [
    "\n",
    "from sklearn import datasets\n",
    "from sklearn.neighbors import KNeighborsClassifier\n",
    "from sklearn.model_selection import train_test_split\n",
    "import pandas as pd\n"
   ],
   "id": "e59b7088d8e98cfd",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 1.2导入水果数据并查看数据特征 ",
   "id": "f26617d1794af9dd"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:41.361554Z",
     "start_time": "2024-12-04T14:32:41.343030Z"
    }
   },
   "cell_type": "code",
   "source": [
    "fruit = pd.read_csv(\"./data/fruit_data.txt\",sep = '\\t')\n",
    "X = fruit.iloc[:,1:]\n",
    "Y = fruit.iloc[:,0].T"
   ],
   "id": "ecfebaf9a1719a2d",
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码用来读取一个名为 `fruit_data.txt` 的文件并对其数据进行初步处理，以下是每行代码的详细解释：\n",
    "\n",
    "### 1. `fruit = pd.read_csv(\"./data/fruit_data.txt\", sep='\\t')`\n",
    "- **作用**：使用 `pandas` 库中的 `read_csv` 函数读取一个以制表符 (`\\t`) 分隔的文本文件。\n",
    "- **参数解释**：\n",
    "  - `\"./data/fruit_data.txt\"`：指定文件的路径，文件位于当前工作目录的 `data` 文件夹下。\n",
    "  - `sep='\\t'`：指定文件的列是以制表符（`\\t`）分隔的。\n",
    "- **结果**：将文件内容读入 `pandas` 的 DataFrame（表格形式的数据结构）中，变量 `fruit` 存储了该表格数据。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. `x = fruit.iloc[:, 1:]`\n",
    "- **作用**：从 `fruit` 数据中提取所有行和第 2 列到最后一列的数据（`iloc` 用于基于索引的位置提取数据）。\n",
    "- **详细说明**：\n",
    "  - `iloc` 是 `pandas` 提供的按位置索引的方法。\n",
    "  - `:` 表示选择所有行。\n",
    "  - `1:` 表示选择从第 2 列（位置索引为 1）到最后一列的所有列（索引从 0 开始）。\n",
    "- **结果**：`x` 是一个新的 DataFrame，包含了 `fruit` 中的特征数据（假设这些列存储了描述水果特征的值）。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. `Y = fruit.iloc[:, 0].T`\n",
    "- **作用**：从 `fruit` 数据中提取第 1 列的数据并进行转置（`.T`）。\n",
    "- **详细说明**：\n",
    "  - `iloc[:, 0]`：选择所有行和第 1 列的数据（通常是标签列，用来存储水果的类别或名称）。\n",
    "  - `.T`：将提取的列进行转置。转置在这个情况下的作用可能只是为了确保数据的维度格式是预期的（从 Series 转换为一维数组）。\n",
    "- **结果**：`Y` 是一个一维的序列（或数组），存储了每个水果对应的标签或类别。\n",
    "\n",
    "---\n",
    "\n",
    "### 综合作用\n",
    "- 这段代码将 `fruit_data.txt` 文件的内容分为两个部分：\n",
    "  1. **`x`**：特征数据，存储描述每种水果的属性（如颜色、大小等）。\n",
    "  2. **`Y`**：目标标签，存储每种水果的类别或名称（可能是用于分类任务）。\n",
    "\n",
    "### 示例数据结构\n",
    "假设 `fruit_data.txt` 的内容如下：\n",
    "```\n",
    "Name    Color   Size    Weight\n",
    "Apple   Red     3       200\n",
    "Banana  Yellow  5       120\n",
    "Orange  Orange  4       150\n",
    "```\n",
    "\n",
    "运行代码后的结果：\n",
    "- `x`：\n",
    "  ```\n",
    "      Color  Size  Weight\n",
    "  0    Red     3     200\n",
    "  1  Yellow     5     120\n",
    "  2  Orange     4     150\n",
    "  ```\n",
    "- `Y`：\n",
    "  ```\n",
    "  0     Apple\n",
    "  1    Banana\n",
    "  2    Orange\n",
    "  Name: Name, dtype: object\n",
    "  ```"
   ],
   "id": "f9d2502f74f8742f"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:41.425558Z",
     "start_time": "2024-12-04T14:32:41.396565Z"
    }
   },
   "cell_type": "code",
   "source": "X ",
   "id": "4f3054462088e5c9",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "    192  8.4   7.3  0.55\n",
       "0   180  8.0   6.8  0.59\n",
       "1   176  7.4   7.2  0.60\n",
       "2    86  6.2   4.7  0.80\n",
       "3    84  6.0   4.6  0.79\n",
       "4    80  5.8   4.3  0.77\n",
       "5    80  5.9   4.3  0.81\n",
       "6    76  5.8   4.0  0.81\n",
       "7   178  7.1   7.8  0.92\n",
       "8   172  7.4   7.0  0.89\n",
       "9   166  6.9   7.3  0.93\n",
       "10  172  7.1   7.6  0.92\n",
       "11  154  7.0   7.1  0.88\n",
       "12  164  7.3   7.7  0.70\n",
       "13  152  7.6   7.3  0.69\n",
       "14  156  7.7   7.1  0.69\n",
       "15  156  7.6   7.5  0.67\n",
       "16  168  7.5   7.6  0.73\n",
       "17  162  7.5   7.1  0.83\n",
       "18  162  7.4   7.2  0.85\n",
       "19  160  7.5   7.5  0.86\n",
       "20  156  7.4   7.4  0.84\n",
       "21  140  7.3   7.1  0.87\n",
       "22  170  7.6   7.9  0.88\n",
       "23  342  9.0   9.4  0.75\n",
       "24  356  9.2   9.2  0.75\n",
       "25  362  9.6   9.2  0.74\n",
       "26  204  7.5   9.2  0.77\n",
       "27  140  6.7   7.1  0.72\n",
       "28  160  7.0   7.4  0.81\n",
       "29  158  7.1   7.5  0.79\n",
       "30  210  7.8   8.0  0.82\n",
       "31  164  7.2   7.0  0.80\n",
       "32  190  7.5   8.1  0.74\n",
       "33  142  7.6   7.8  0.75\n",
       "34  150  7.1   7.9  0.75\n",
       "35  160  7.1   7.6  0.76\n",
       "36  154  7.3   7.3  0.79\n",
       "37  158  7.2   7.8  0.77\n",
       "38  144  6.8   7.4  0.75\n",
       "39  154  7.1   7.5  0.78\n",
       "40  180  7.6   8.2  0.79\n",
       "41  154  7.2   7.2  0.82\n",
       "42  194  7.2  10.3  0.70\n",
       "43  200  7.3  10.5  0.72\n",
       "44  186  7.2   9.2  0.72\n",
       "45  216  7.3  10.2  0.71\n",
       "46  196  7.3   9.7  0.72\n",
       "47  174  7.3  10.1  0.72\n",
       "48  132  5.8   8.7  0.73\n",
       "49  130  6.0   8.2  0.71\n",
       "50  116  6.0   7.5  0.72\n",
       "51  118  5.9   8.0  0.72\n",
       "52  120  6.0   8.4  0.74\n",
       "53  116  6.1   8.5  0.71\n",
       "54  116  6.3   7.7  0.72\n",
       "55  116  5.9   8.1  0.73\n",
       "56  152  6.5   8.5  0.72\n",
       "57  118  6.1   8.1  0.70"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>192</th>\n",
       "      <th>8.4</th>\n",
       "      <th>7.3</th>\n",
       "      <th>0.55</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>180</td>\n",
       "      <td>8.0</td>\n",
       "      <td>6.8</td>\n",
       "      <td>0.59</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>176</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.2</td>\n",
       "      <td>0.60</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>86</td>\n",
       "      <td>6.2</td>\n",
       "      <td>4.7</td>\n",
       "      <td>0.80</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>84</td>\n",
       "      <td>6.0</td>\n",
       "      <td>4.6</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>80</td>\n",
       "      <td>5.8</td>\n",
       "      <td>4.3</td>\n",
       "      <td>0.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>80</td>\n",
       "      <td>5.9</td>\n",
       "      <td>4.3</td>\n",
       "      <td>0.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>76</td>\n",
       "      <td>5.8</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>178</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.8</td>\n",
       "      <td>0.92</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>172</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.0</td>\n",
       "      <td>0.89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>166</td>\n",
       "      <td>6.9</td>\n",
       "      <td>7.3</td>\n",
       "      <td>0.93</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>172</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.6</td>\n",
       "      <td>0.92</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>154</td>\n",
       "      <td>7.0</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>164</td>\n",
       "      <td>7.3</td>\n",
       "      <td>7.7</td>\n",
       "      <td>0.70</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>152</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.3</td>\n",
       "      <td>0.69</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>156</td>\n",
       "      <td>7.7</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.69</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>156</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.67</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>168</td>\n",
       "      <td>7.5</td>\n",
       "      <td>7.6</td>\n",
       "      <td>0.73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>162</td>\n",
       "      <td>7.5</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>162</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.2</td>\n",
       "      <td>0.85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>160</td>\n",
       "      <td>7.5</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.86</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>156</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.4</td>\n",
       "      <td>0.84</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>140</td>\n",
       "      <td>7.3</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.87</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>170</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.9</td>\n",
       "      <td>0.88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>342</td>\n",
       "      <td>9.0</td>\n",
       "      <td>9.4</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>356</td>\n",
       "      <td>9.2</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>362</td>\n",
       "      <td>9.6</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>204</td>\n",
       "      <td>7.5</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>140</td>\n",
       "      <td>6.7</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>160</td>\n",
       "      <td>7.0</td>\n",
       "      <td>7.4</td>\n",
       "      <td>0.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>158</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>210</td>\n",
       "      <td>7.8</td>\n",
       "      <td>8.0</td>\n",
       "      <td>0.82</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>164</td>\n",
       "      <td>7.2</td>\n",
       "      <td>7.0</td>\n",
       "      <td>0.80</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>190</td>\n",
       "      <td>7.5</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>142</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.8</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34</th>\n",
       "      <td>150</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.9</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>35</th>\n",
       "      <td>160</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.6</td>\n",
       "      <td>0.76</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36</th>\n",
       "      <td>154</td>\n",
       "      <td>7.3</td>\n",
       "      <td>7.3</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37</th>\n",
       "      <td>158</td>\n",
       "      <td>7.2</td>\n",
       "      <td>7.8</td>\n",
       "      <td>0.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>38</th>\n",
       "      <td>144</td>\n",
       "      <td>6.8</td>\n",
       "      <td>7.4</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>39</th>\n",
       "      <td>154</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.78</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>180</td>\n",
       "      <td>7.6</td>\n",
       "      <td>8.2</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>41</th>\n",
       "      <td>154</td>\n",
       "      <td>7.2</td>\n",
       "      <td>7.2</td>\n",
       "      <td>0.82</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>42</th>\n",
       "      <td>194</td>\n",
       "      <td>7.2</td>\n",
       "      <td>10.3</td>\n",
       "      <td>0.70</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>43</th>\n",
       "      <td>200</td>\n",
       "      <td>7.3</td>\n",
       "      <td>10.5</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>44</th>\n",
       "      <td>186</td>\n",
       "      <td>7.2</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>216</td>\n",
       "      <td>7.3</td>\n",
       "      <td>10.2</td>\n",
       "      <td>0.71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>196</td>\n",
       "      <td>7.3</td>\n",
       "      <td>9.7</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>47</th>\n",
       "      <td>174</td>\n",
       "      <td>7.3</td>\n",
       "      <td>10.1</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>48</th>\n",
       "      <td>132</td>\n",
       "      <td>5.8</td>\n",
       "      <td>8.7</td>\n",
       "      <td>0.73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>130</td>\n",
       "      <td>6.0</td>\n",
       "      <td>8.2</td>\n",
       "      <td>0.71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50</th>\n",
       "      <td>116</td>\n",
       "      <td>6.0</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>51</th>\n",
       "      <td>118</td>\n",
       "      <td>5.9</td>\n",
       "      <td>8.0</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52</th>\n",
       "      <td>120</td>\n",
       "      <td>6.0</td>\n",
       "      <td>8.4</td>\n",
       "      <td>0.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>53</th>\n",
       "      <td>116</td>\n",
       "      <td>6.1</td>\n",
       "      <td>8.5</td>\n",
       "      <td>0.71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>54</th>\n",
       "      <td>116</td>\n",
       "      <td>6.3</td>\n",
       "      <td>7.7</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>55</th>\n",
       "      <td>116</td>\n",
       "      <td>5.9</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0.73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>56</th>\n",
       "      <td>152</td>\n",
       "      <td>6.5</td>\n",
       "      <td>8.5</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>57</th>\n",
       "      <td>118</td>\n",
       "      <td>6.1</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0.70</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:41.536097Z",
     "start_time": "2024-12-04T14:32:41.523075Z"
    }
   },
   "cell_type": "code",
   "source": "Y",
   "id": "e854120b6b124a9c",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0     1\n",
       "1     1\n",
       "2     2\n",
       "3     2\n",
       "4     2\n",
       "5     2\n",
       "6     2\n",
       "7     1\n",
       "8     1\n",
       "9     1\n",
       "10    1\n",
       "11    1\n",
       "12    1\n",
       "13    1\n",
       "14    1\n",
       "15    1\n",
       "16    1\n",
       "17    1\n",
       "18    1\n",
       "19    1\n",
       "20    1\n",
       "21    1\n",
       "22    1\n",
       "23    3\n",
       "24    3\n",
       "25    3\n",
       "26    3\n",
       "27    3\n",
       "28    3\n",
       "29    3\n",
       "30    3\n",
       "31    3\n",
       "32    3\n",
       "33    3\n",
       "34    3\n",
       "35    3\n",
       "36    3\n",
       "37    3\n",
       "38    3\n",
       "39    3\n",
       "40    3\n",
       "41    3\n",
       "42    4\n",
       "43    4\n",
       "44    4\n",
       "45    4\n",
       "46    4\n",
       "47    4\n",
       "48    4\n",
       "49    4\n",
       "50    4\n",
       "51    4\n",
       "52    4\n",
       "53    4\n",
       "54    4\n",
       "55    4\n",
       "56    4\n",
       "57    4\n",
       "Name: 1, dtype: int64"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 1.3划分数据集为训练集和测试集\n",
    "\n"
   ],
   "id": "f47271864967bbdc"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:41.630745Z",
     "start_time": "2024-12-04T14:32:41.616747Z"
    }
   },
   "cell_type": "code",
   "source": "fruit_train_x,fruit_test_x,fruit_train_y,fruit_test_y = train_test_split(X,Y,test_size=0.2,random_state=0)",
   "id": "ded65171070cc68f",
   "outputs": [],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码使用了 `train_test_split` 函数将数据集 `X` 和 `Y` 按一定比例划分为训练集和测试集。以下是详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### **1. train_test_split 函数的作用**\n",
    "- `train_test_split` 是 `sklearn.model_selection` 中的一个函数，用于随机划分数据集，通常用于将数据集分为**训练集**和**测试集**。\n",
    "- 参数：\n",
    "  - `X`：特征数据集（输入数据，例如水果的颜色、大小等）。\n",
    "  - `Y`：标签数据集（目标变量，例如水果的名称或类别）。\n",
    "  - `test_size=0.2`：测试集的比例，这里指定为 20%。\n",
    "  - `random_state=0`：随机种子，确保数据集划分的随机性可复现（相同的种子会产生相同的随机结果）。\n",
    "- 返回值：\n",
    "  - 返回四个数据集：`X_train`、`X_test`、`y_train`、`y_test`。\n",
    "\n",
    "---\n",
    "\n",
    "### **2. 变量拆分**\n",
    "```python\n",
    "fruit_train_x, fruit_train_y, fruit_test_x, fruit_test_y = train_test_split(X, Y, test_size=0.2, random_state=0)\n",
    "```\n",
    "- **`X`**：特征数据集，原始数据的输入部分。\n",
    "- **`Y`**：目标数据集，原始数据的输出部分。\n",
    "- **`test_size=0.2`**：指定测试集占比为 20%，即将 80% 的数据用于训练，20% 的数据用于测试。\n",
    "- 返回结果：\n",
    "  1. **`fruit_train_x`**：训练集中的特征数据（占 80%）。\n",
    "  2. **`fruit_train_y`**：训练集中的标签数据（占 80%）。\n",
    "  3. **`fruit_test_x`**：测试集中的特征数据（占 20%）。\n",
    "  4. **`fruit_test_y`**：测试集中的标签数据（占 20%）。\n",
    "\n",
    "---\n",
    "\n",
    "### **3. 代码运行后数据集的用途**\n",
    "- **训练集**：\n",
    "  - `fruit_train_x` 和 `fruit_train_y` 用于训练机器学习模型。\n",
    "  - 模型会基于训练集的数据学会如何将特征与目标关联起来。\n",
    "- **测试集**：\n",
    "  - `fruit_test_x` 和 `fruit_test_y` 用于验证模型的性能。\n",
    "  - 通过将测试集特征输入模型，比较模型预测的结果和 `fruit_test_y` 的实际值，评估模型的准确性。\n",
    "\n",
    "---\n",
    "\n",
    "### **示例**\n",
    "假设 `X` 和 `Y` 的内容如下：\n",
    "\n",
    "#### 数据：\n",
    "- `X`（特征）：\n",
    "  ```\n",
    "      Color  Size  Weight\n",
    "  0    Red     3     200\n",
    "  1  Yellow     5     120\n",
    "  2  Orange     4     150\n",
    "  3    Red     6     180\n",
    "  4  Yellow     4     100\n",
    "  ```\n",
    "- `Y`（目标）：\n",
    "  ```\n",
    "  0     Apple\n",
    "  1    Banana\n",
    "  2    Orange\n",
    "  3     Apple\n",
    "  4    Banana\n",
    "  ```\n",
    "\n",
    "#### 分割结果：\n",
    "运行代码后，假设划分如下：\n",
    "- `fruit_train_x`：\n",
    "  ```\n",
    "      Color  Size  Weight\n",
    "  1  Yellow     5     120\n",
    "  3    Red     6     180\n",
    "  4  Yellow     4     100\n",
    "  0    Red     3     200\n",
    "  ```\n",
    "- `fruit_train_y`：\n",
    "  ```\n",
    "  1    Banana\n",
    "  3     Apple\n",
    "  4    Banana\n",
    "  0     Apple\n",
    "  ```\n",
    "- `fruit_test_x`：\n",
    "  ```\n",
    "      Color  Size  Weight\n",
    "  2  Orange     4     150\n",
    "  ```\n",
    "- `fruit_test_y`：\n",
    "  ```\n",
    "  2    Orange\n",
    "  ```\n",
    "\n",
    "### 总结\n",
    "`train_test_split` 函数通过随机划分数据集，帮助你生成训练集和测试集，为模型训练和性能评估提供基础数据。"
   ],
   "id": "18bb3c2c75b2b0e1"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:41.881937Z",
     "start_time": "2024-12-04T14:32:41.852843Z"
    }
   },
   "cell_type": "code",
   "source": "fruit_train_x",
   "id": "53c7d47c42335097",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "    192  8.4   7.3  0.55\n",
       "29  158  7.1   7.5  0.79\n",
       "40  180  7.6   8.2  0.79\n",
       "32  190  7.5   8.1  0.74\n",
       "41  154  7.2   7.2  0.82\n",
       "37  158  7.2   7.8  0.77\n",
       "7   178  7.1   7.8  0.92\n",
       "14  156  7.7   7.1  0.69\n",
       "31  164  7.2   7.0  0.80\n",
       "28  160  7.0   7.4  0.81\n",
       "56  152  6.5   8.5  0.72\n",
       "52  120  6.0   8.4  0.74\n",
       "18  162  7.4   7.2  0.85\n",
       "54  116  6.3   7.7  0.72\n",
       "26  204  7.5   9.2  0.77\n",
       "15  156  7.6   7.5  0.67\n",
       "5    80  5.9   4.3  0.81\n",
       "30  210  7.8   8.0  0.82\n",
       "16  168  7.5   7.6  0.73\n",
       "49  130  6.0   8.2  0.71\n",
       "20  156  7.4   7.4  0.84\n",
       "50  116  6.0   7.5  0.72\n",
       "8   172  7.4   7.0  0.89\n",
       "13  152  7.6   7.3  0.69\n",
       "25  362  9.6   9.2  0.74\n",
       "17  162  7.5   7.1  0.83\n",
       "43  200  7.3  10.5  0.72\n",
       "46  196  7.3   9.7  0.72\n",
       "51  118  5.9   8.0  0.72\n",
       "38  144  6.8   7.4  0.75\n",
       "1   176  7.4   7.2  0.60\n",
       "12  164  7.3   7.7  0.70\n",
       "57  118  6.1   8.1  0.70\n",
       "24  356  9.2   9.2  0.75\n",
       "6    76  5.8   4.0  0.81\n",
       "23  342  9.0   9.4  0.75\n",
       "36  154  7.3   7.3  0.79\n",
       "21  140  7.3   7.1  0.87\n",
       "19  160  7.5   7.5  0.86\n",
       "9   166  6.9   7.3  0.93\n",
       "39  154  7.1   7.5  0.78\n",
       "55  116  5.9   8.1  0.73\n",
       "3    84  6.0   4.6  0.79\n",
       "0   180  8.0   6.8  0.59\n",
       "53  116  6.1   8.5  0.71\n",
       "47  174  7.3  10.1  0.72\n",
       "44  186  7.2   9.2  0.72"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>192</th>\n",
       "      <th>8.4</th>\n",
       "      <th>7.3</th>\n",
       "      <th>0.55</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>29</th>\n",
       "      <td>158</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>40</th>\n",
       "      <td>180</td>\n",
       "      <td>7.6</td>\n",
       "      <td>8.2</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>32</th>\n",
       "      <td>190</td>\n",
       "      <td>7.5</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>41</th>\n",
       "      <td>154</td>\n",
       "      <td>7.2</td>\n",
       "      <td>7.2</td>\n",
       "      <td>0.82</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>37</th>\n",
       "      <td>158</td>\n",
       "      <td>7.2</td>\n",
       "      <td>7.8</td>\n",
       "      <td>0.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>178</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.8</td>\n",
       "      <td>0.92</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>14</th>\n",
       "      <td>156</td>\n",
       "      <td>7.7</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.69</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>31</th>\n",
       "      <td>164</td>\n",
       "      <td>7.2</td>\n",
       "      <td>7.0</td>\n",
       "      <td>0.80</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>28</th>\n",
       "      <td>160</td>\n",
       "      <td>7.0</td>\n",
       "      <td>7.4</td>\n",
       "      <td>0.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>56</th>\n",
       "      <td>152</td>\n",
       "      <td>6.5</td>\n",
       "      <td>8.5</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>52</th>\n",
       "      <td>120</td>\n",
       "      <td>6.0</td>\n",
       "      <td>8.4</td>\n",
       "      <td>0.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>162</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.2</td>\n",
       "      <td>0.85</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>54</th>\n",
       "      <td>116</td>\n",
       "      <td>6.3</td>\n",
       "      <td>7.7</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>26</th>\n",
       "      <td>204</td>\n",
       "      <td>7.5</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>15</th>\n",
       "      <td>156</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.67</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>80</td>\n",
       "      <td>5.9</td>\n",
       "      <td>4.3</td>\n",
       "      <td>0.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>30</th>\n",
       "      <td>210</td>\n",
       "      <td>7.8</td>\n",
       "      <td>8.0</td>\n",
       "      <td>0.82</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>16</th>\n",
       "      <td>168</td>\n",
       "      <td>7.5</td>\n",
       "      <td>7.6</td>\n",
       "      <td>0.73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>49</th>\n",
       "      <td>130</td>\n",
       "      <td>6.0</td>\n",
       "      <td>8.2</td>\n",
       "      <td>0.71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>20</th>\n",
       "      <td>156</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.4</td>\n",
       "      <td>0.84</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50</th>\n",
       "      <td>116</td>\n",
       "      <td>6.0</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>172</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.0</td>\n",
       "      <td>0.89</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>13</th>\n",
       "      <td>152</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.3</td>\n",
       "      <td>0.69</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25</th>\n",
       "      <td>362</td>\n",
       "      <td>9.6</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.74</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>17</th>\n",
       "      <td>162</td>\n",
       "      <td>7.5</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.83</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>43</th>\n",
       "      <td>200</td>\n",
       "      <td>7.3</td>\n",
       "      <td>10.5</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>46</th>\n",
       "      <td>196</td>\n",
       "      <td>7.3</td>\n",
       "      <td>9.7</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>51</th>\n",
       "      <td>118</td>\n",
       "      <td>5.9</td>\n",
       "      <td>8.0</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>38</th>\n",
       "      <td>144</td>\n",
       "      <td>6.8</td>\n",
       "      <td>7.4</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>176</td>\n",
       "      <td>7.4</td>\n",
       "      <td>7.2</td>\n",
       "      <td>0.60</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>12</th>\n",
       "      <td>164</td>\n",
       "      <td>7.3</td>\n",
       "      <td>7.7</td>\n",
       "      <td>0.70</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>57</th>\n",
       "      <td>118</td>\n",
       "      <td>6.1</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0.70</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>24</th>\n",
       "      <td>356</td>\n",
       "      <td>9.2</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>76</td>\n",
       "      <td>5.8</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0.81</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>23</th>\n",
       "      <td>342</td>\n",
       "      <td>9.0</td>\n",
       "      <td>9.4</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>36</th>\n",
       "      <td>154</td>\n",
       "      <td>7.3</td>\n",
       "      <td>7.3</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>21</th>\n",
       "      <td>140</td>\n",
       "      <td>7.3</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.87</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>19</th>\n",
       "      <td>160</td>\n",
       "      <td>7.5</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.86</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>166</td>\n",
       "      <td>6.9</td>\n",
       "      <td>7.3</td>\n",
       "      <td>0.93</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>39</th>\n",
       "      <td>154</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.5</td>\n",
       "      <td>0.78</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>55</th>\n",
       "      <td>116</td>\n",
       "      <td>5.9</td>\n",
       "      <td>8.1</td>\n",
       "      <td>0.73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>84</td>\n",
       "      <td>6.0</td>\n",
       "      <td>4.6</td>\n",
       "      <td>0.79</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>180</td>\n",
       "      <td>8.0</td>\n",
       "      <td>6.8</td>\n",
       "      <td>0.59</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>53</th>\n",
       "      <td>116</td>\n",
       "      <td>6.1</td>\n",
       "      <td>8.5</td>\n",
       "      <td>0.71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>47</th>\n",
       "      <td>174</td>\n",
       "      <td>7.3</td>\n",
       "      <td>10.1</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>44</th>\n",
       "      <td>186</td>\n",
       "      <td>7.2</td>\n",
       "      <td>9.2</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:42.024139Z",
     "start_time": "2024-12-04T14:32:42.001544Z"
    }
   },
   "cell_type": "code",
   "source": "fruit_test_x",
   "id": "d689ac6022f578e8",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "    192  8.4   7.3  0.55\n",
       "35  160  7.1   7.6  0.76\n",
       "34  150  7.1   7.9  0.75\n",
       "42  194  7.2  10.3  0.70\n",
       "27  140  6.7   7.1  0.72\n",
       "11  154  7.0   7.1  0.88\n",
       "2    86  6.2   4.7  0.80\n",
       "33  142  7.6   7.8  0.75\n",
       "45  216  7.3  10.2  0.71\n",
       "22  170  7.6   7.9  0.88\n",
       "48  132  5.8   8.7  0.73\n",
       "4    80  5.8   4.3  0.77\n",
       "10  172  7.1   7.6  0.92"
      ],
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>192</th>\n",
       "      <th>8.4</th>\n",
       "      <th>7.3</th>\n",
       "      <th>0.55</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>35</th>\n",
       "      <td>160</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.6</td>\n",
       "      <td>0.76</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>34</th>\n",
       "      <td>150</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.9</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>42</th>\n",
       "      <td>194</td>\n",
       "      <td>7.2</td>\n",
       "      <td>10.3</td>\n",
       "      <td>0.70</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>27</th>\n",
       "      <td>140</td>\n",
       "      <td>6.7</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.72</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>11</th>\n",
       "      <td>154</td>\n",
       "      <td>7.0</td>\n",
       "      <td>7.1</td>\n",
       "      <td>0.88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>86</td>\n",
       "      <td>6.2</td>\n",
       "      <td>4.7</td>\n",
       "      <td>0.80</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>33</th>\n",
       "      <td>142</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.8</td>\n",
       "      <td>0.75</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>45</th>\n",
       "      <td>216</td>\n",
       "      <td>7.3</td>\n",
       "      <td>10.2</td>\n",
       "      <td>0.71</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>22</th>\n",
       "      <td>170</td>\n",
       "      <td>7.6</td>\n",
       "      <td>7.9</td>\n",
       "      <td>0.88</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>48</th>\n",
       "      <td>132</td>\n",
       "      <td>5.8</td>\n",
       "      <td>8.7</td>\n",
       "      <td>0.73</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>80</td>\n",
       "      <td>5.8</td>\n",
       "      <td>4.3</td>\n",
       "      <td>0.77</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>10</th>\n",
       "      <td>172</td>\n",
       "      <td>7.1</td>\n",
       "      <td>7.6</td>\n",
       "      <td>0.92</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 1.4 模型构建与训练",
   "id": "83d7c83f4bc1f486"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:42.304545Z",
     "start_time": "2024-12-04T14:32:42.275535Z"
    }
   },
   "cell_type": "code",
   "source": [
    "knn = KNeighborsClassifier()\n",
    "knn.fit(fruit_train_x, fruit_train_y)"
   ],
   "id": "f50f331ab62384b",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "KNeighborsClassifier()"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: black;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: block;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 1ex;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow fitted\">&nbsp;&nbsp;KNeighborsClassifier<a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.5/modules/generated/sklearn.neighbors.KNeighborsClassifier.html\">?<span>Documentation for KNeighborsClassifier</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></label><div class=\"sk-toggleable__content fitted\"><pre>KNeighborsClassifier()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码用于创建和训练一个 K 近邻（**K-Nearest Neighbors，KNN**）分类模型，以下是详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. **`KNeighborsClassifier` 的作用**\n",
    "- **`KNeighborsClassifier`** 是 scikit-learn 中实现 KNN 算法的分类器。\n",
    "- KNN 是一种基于实例的学习算法，它通过计算输入样本与训练数据集中所有样本的距离，选择距离最近的 **K** 个样本（默认 K=5），根据这些样本的类别进行预测。\n",
    "- 特点：\n",
    "  - 简单直观，无需显式训练过程（主要是在预测阶段计算距离）。\n",
    "  - 适用于小型数据集和低维特征。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. **`knn = KNeighborsClassifier()`**\n",
    "- 创建一个 KNN 分类器对象。\n",
    "- 默认参数解释：\n",
    "  - **`n_neighbors=5`**：选择 5 个最近邻作为决策依据。\n",
    "  - **`metric='minkowski'`**：使用 Minkowski 距离作为距离度量，p=2 时等价于欧几里得距离。\n",
    "  - **`weights='uniform'`**：所有邻居的权重相等（不考虑距离权重）。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. **`knn.fit(fruit_train_x, fruit_train_y)`**\n",
    "- **作用**：使用训练数据集 `fruit_train_x`（特征数据）和 `fruit_train_y`（标签数据）来训练 KNN 分类器。\n",
    "- **内部机制**：\n",
    "  - KNN 不需要显式训练模型，只是将训练数据存储在内存中。\n",
    "  - 在预测时，根据输入样本计算它与训练集的距离，并选出最近的 **K** 个样本进行投票分类。\n",
    "- **输入参数**：\n",
    "  - `fruit_train_x`：训练集的特征数据（通常是二维表格，每行一个样本，每列一个特征）。\n",
    "  - `fruit_train_y`：训练集的目标数据（每个样本的标签，通常是一维数组或列表）。\n",
    "\n",
    "---\n",
    "\n",
    "### 4. **代码运行后的结果**\n",
    "- `knn`：一个已经存储了训练数据的 KNN 分类器对象。\n",
    "- 此时模型已经准备好，可以使用 `.predict()` 方法对新数据进行分类预测。\n",
    "\n",
    "---\n",
    "\n",
    "### 示例\n",
    "#### 假设数据：\n",
    "- `fruit_train_x`：\n",
    "  ```\n",
    "      Size  Weight\n",
    "  0     3     200\n",
    "  1     5     120\n",
    "  2     4     150\n",
    "  ```\n",
    "- `fruit_train_y`：\n",
    "  ```\n",
    "  0    Apple\n",
    "  1    Banana\n",
    "  2    Orange\n",
    "  ```\n",
    "\n",
    "#### 代码解释：\n",
    "```python\n",
    "knn = KNeighborsClassifier()       # 创建 KNN 分类器对象，默认 k=5\n",
    "knn.fit(fruit_train_x, fruit_train_y)  # 使用训练数据拟合模型\n",
    "```\n",
    "\n",
    "#### 预测：\n",
    "```python\n",
    "new_sample = [[4, 140]]           # 新样本：大小为 4，重量为 140\n",
    "prediction = knn.predict(new_sample)\n",
    "print(prediction)                 # 输出预测结果\n",
    "```\n",
    "输出可能为：\n",
    "```\n",
    "['Orange']\n",
    "```\n",
    "解释：根据 KNN 的计算，模型判断新样本更接近“Orange”的特征。\n",
    "\n",
    "---\n",
    "\n",
    "### 总结\n",
    "这段代码完成了 KNN 分类器的创建和拟合过程。模型随后可以通过 `.predict()` 方法对测试数据或新样本进行分类预测。"
   ],
   "id": "d3ba3293f27e4c6"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 1.5 对水果数据进行预测，计算准确率，并打印结果",
   "id": "dfac055c5b4f1d02"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:42.647713Z",
     "start_time": "2024-12-04T14:32:42.624711Z"
    }
   },
   "cell_type": "code",
   "source": [
    "predict_result = knn.predict(fruit_test_x)\n",
    "print(\"测试集大小:\",fruit_test_x.shape)\n",
    "print(\"真实结果:\\n\",fruit_test_y)\n",
    "print(\"预测结果:\",predict_result)\n",
    "print(\"预测精确值:\",knn.score(fruit_test_x,fruit_test_y))"
   ],
   "id": "366f1afdbb73e5a2",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "测试集大小: (12, 4)\n",
      "真实结果:\n",
      " 35    3\n",
      "34    3\n",
      "42    4\n",
      "27    3\n",
      "11    1\n",
      "2     2\n",
      "33    3\n",
      "45    4\n",
      "22    1\n",
      "48    4\n",
      "4     2\n",
      "10    1\n",
      "Name: 1, dtype: int64\n",
      "预测结果: [3 3 4 1 3 2 1 3 1 4 2 1]\n",
      "预测精确值: 0.6666666666666666\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码用于测试 KNN 模型在测试集上的预测性能，并输出预测结果和模型的精确度。以下是详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### **1. `predict_result = knn.predict(fruit_test_x)`**\n",
    "- **作用**：对测试集的特征数据 `fruit_test_x` 进行预测，输出预测的类别标签。\n",
    "- **内部过程**：\n",
    "  - `knn` 是已经训练好的 KNN 模型。\n",
    "  - 调用 `.predict()` 方法，会对 `fruit_test_x` 中的每一个样本计算它与训练集中所有样本的距离。\n",
    "  - 找出最近的 K 个样本，根据它们的类别通过投票方式决定测试样本的类别。\n",
    "- **输出**：\n",
    "  - `predict_result` 是一个一维数组，包含对 `fruit_test_x` 中每个样本的预测类别。\n",
    "\n",
    "---\n",
    "\n",
    "### **2. `print(\"测试集大小：\", fruit_test_x.shape)`**\n",
    "- **作用**：打印测试集的大小，即测试集中样本数和特征数。\n",
    "- **`fruit_test_x.shape`**：\n",
    "  - 是一个元组 `(n_samples, n_features)`，分别表示测试集的样本数量和每个样本的特征数量。\n",
    "\n",
    "---\n",
    "\n",
    "### **3. `print(\"真实结果：\", fruit_test_y)`**\n",
    "- **作用**：打印测试集中每个样本的真实类别标签（`fruit_test_y`）。\n",
    "- **`fruit_test_y`**：\n",
    "  - 是一个一维数组或 Series，存储了测试集中每个样本对应的真实类别。\n",
    "\n",
    "---\n",
    "\n",
    "### **4. `print(\"预测结果：\", predict_result)`**\n",
    "- **作用**：打印模型对测试集的预测结果（`predict_result`）。\n",
    "- **对比**：\n",
    "  - 可以通过与 `fruit_test_y` 对比，观察预测是否正确。\n",
    "\n",
    "---\n",
    "\n",
    "### **5. `print(\"预测精确值：\", knn.score(fruit_test_x, fruit_test_y))`**\n",
    "- **作用**：计算并打印模型在测试集上的准确率。\n",
    "- **内部过程**：\n",
    "  - `knn.score()` 方法会自动调用 `.predict(fruit_test_x)` 获取预测结果。\n",
    "  - 然后将预测结果与真实标签 `fruit_test_y` 进行对比，计算预测准确率（正确预测的样本数占总样本数的比例）。\n",
    "- **输出**：\n",
    "  - `knn.score(fruit_test_x, fruit_test_y)` 返回一个浮点数，表示模型的预测准确率。\n",
    "\n",
    "---\n",
    "\n",
    "### 示例\n",
    "\n",
    "假设数据如下：\n",
    "#### 测试集特征（`fruit_test_x`）：\n",
    "```\n",
    "   Size  Weight\n",
    "0     3     200\n",
    "1     4     150\n",
    "```\n",
    "\n",
    "#### 测试集标签（`fruit_test_y`）：\n",
    "```\n",
    "0    Apple\n",
    "1    Orange\n",
    "```\n",
    "\n",
    "#### 预测结果（`predict_result`）：\n",
    "```\n",
    "0    Apple\n",
    "1    Orange\n",
    "```\n",
    "\n",
    "运行代码输出：\n",
    "```python\n",
    "测试集大小： (2, 2)\n",
    "真实结果： ['Apple', 'Orange']\n",
    "预测结果： ['Apple', 'Orange']\n",
    "预测精确值： 1.0\n",
    "```\n",
    "解释：\n",
    "- 测试集中共有 2 个样本，每个样本有 2 个特征。\n",
    "- 模型预测的结果与真实结果完全一致，因此准确率为 1.0（100%）。\n",
    "\n",
    "---\n",
    "\n",
    "### 总结\n",
    "- **`knn.predict()`**：生成模型的预测结果。\n",
    "- **测试集大小**、**真实结果** 和 **预测结果** 用于验证模型的性能。\n",
    "- **`knn.score()`**：提供了一个快速计算准确率的方法，是评价模型性能的重要指标之一。"
   ],
   "id": "77a6bc1c48ebebf2"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 1.6 预测两个测试样本的类别",
   "id": "26f2379209bc5b8b"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:42.933220Z",
     "start_time": "2024-12-04T14:32:42.910206Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "test_x1 = np.array([192,8.4,7.3,0.55]).reshape(1,-1)\n",
    "test_x2 = np.array([200,7.3,10.5,0.72]).reshape(1,-1)\n",
    "test_y1 = knn.predict(test_x1)\n",
    "test_y2 = knn.predict(test_x2)\n",
    "print(\"样本A的类别为：{},样本B的类别是：{}\".format(test_y1,test_y2))"
   ],
   "id": "d4f4e4bd2e176e5a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "样本A的类别为：[4],样本B的类别是：[3]\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Pycharm\\MachineLearning_HM\\.venv\\lib\\site-packages\\sklearn\\base.py:493: UserWarning: X does not have valid feature names, but KNeighborsClassifier was fitted with feature names\n",
      "  warnings.warn(\n",
      "D:\\Pycharm\\MachineLearning_HM\\.venv\\lib\\site-packages\\sklearn\\base.py:493: UserWarning: X does not have valid feature names, but KNeighborsClassifier was fitted with feature names\n",
      "  warnings.warn(\n"
     ]
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码的作用是用已经训练好的 KNN 模型对两个新样本进行分类预测，以下是详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### **代码逐行分析**\n",
    "\n",
    "#### **1. `import numpy as np`**\n",
    "- 导入 NumPy 库，用于处理数组数据。\n",
    "\n",
    "---\n",
    "\n",
    "#### **2. 定义第一个测试样本 `test_x1`**\n",
    "```python\n",
    "test_x1 = np.array([192, 8.4, 7.3, 0.55]).reshape(1, -1)\n",
    "```\n",
    "- **`np.array([192, 8.4, 7.3, 0.55])`**：\n",
    "  - 创建一个包含 4 个特征值的 NumPy 数组，表示一个新样本的数据。\n",
    "  - 假设这 4 个值分别对应训练数据的 4 个特征（如：`Size`、`Weight`、`Feature1`、`Feature2`）。\n",
    "- **`.reshape(1, -1)`**：\n",
    "  - 将数组重塑为二维数组，形状为 `(1, 4)`。\n",
    "  - 这是因为 `knn.predict()` 要求输入的形状为 `[n_samples, n_features]`，即一个样本有多个特征的二维格式。\n",
    "\n",
    "---\n",
    "\n",
    "#### **3. 定义第二个测试样本 `test_x2`**\n",
    "```python\n",
    "test_x2 = np.array([200, 7.3, 10.5, 0.72]).reshape(1, -1)\n",
    "```\n",
    "- 同样创建第二个新样本的特征数据，并重塑为二维数组。\n",
    "\n",
    "---\n",
    "\n",
    "#### **4. 对样本进行预测**\n",
    "```python\n",
    "test_y1 = knn.predict(test_x1)\n",
    "test_y2 = knn.predict(test_x2)\n",
    "```\n",
    "- **`knn.predict()`**：\n",
    "  - 使用 KNN 模型对输入数据进行预测。\n",
    "  - `test_x1` 和 `test_x2` 是输入的新样本。\n",
    "- **预测结果**：\n",
    "  - 返回值 `test_y1` 和 `test_y2` 是预测的类别标签，通常是字符串或数字，取决于训练数据的目标值。\n",
    "\n",
    "---\n",
    "\n",
    "#### **5. 打印预测结果**\n",
    "```python\n",
    "print(\"样本A的类别为：{},样本B的类别是：{}\".format(test_y1, test_y2))\n",
    "```\n",
    "- **`format(test_y1, test_y2)`**：\n",
    "  - 将预测结果 `test_y1` 和 `test_y2` 插入到字符串中，分别表示样本 A 和样本 B 的类别。\n",
    "- **输出示例**：\n",
    "  ```\n",
    "  样本A的类别为：[Apple], 样本B的类别是：[Orange]\n",
    "  ```\n",
    "\n",
    "---\n",
    "\n",
    "### **整体运行逻辑**\n",
    "1. 定义两个新样本的特征数据。\n",
    "2. 使用已经训练好的 KNN 模型对两个样本进行分类预测。\n",
    "3. 输出预测类别。\n",
    "\n",
    "---\n",
    "\n",
    "### **注意事项**\n",
    "1. **数据格式一致性**：\n",
    "   - 确保输入样本的特征数量与训练数据一致（如：4 个特征）。\n",
    "   - 输入数据格式为二维数组，形状为 `[n_samples, n_features]`。\n",
    "\n",
    "2. **特征值范围**：\n",
    "   - 如果训练数据进行了归一化或标准化，预测数据也需要经过相同的预处理步骤，确保数值范围一致。\n",
    "\n",
    "---\n",
    "\n",
    "### 示例输出\n",
    "如果模型的训练数据是关于水果分类的：\n",
    "- 输入的特征代表：尺寸（`Size`）、重量（`Weight`）、某特征1、某特征2。\n",
    "- 输出可能是类别标签，如 `\"Apple\"`、`\"Orange\"`。\n",
    "\n",
    "输出结果：\n",
    "```\n",
    "样本A的类别为：[Orange], 样本B的类别是：[Apple]\n",
    "``\n",
    "`"
   ],
   "id": "ba909709995d4ab7"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 2.基于鸢尾花数据集与scikit-learn实现逻辑回归的交叉验证训练",
   "id": "a034005d3daa03fb"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "基于逻辑回归模型，应用鸢尾花数据集，实现模型交叉验证的调优，请分析给出的相关代码的功能，以及根据给出的功能编写相关的代码\n",
   "id": "69784bb78f24efa1"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.1 导入相应的python包",
   "id": "e430b2a56ff70c80"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:43.059194Z",
     "start_time": "2024-12-04T14:32:43.038659Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "from sklearn.metrics import accuracy_score\n",
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n"
   ],
   "id": "cb6242bb5b7c42e7",
   "outputs": [],
   "execution_count": 13
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "以下是对这段代码的逐行解释：\n",
    "\n",
    "### 1. 导入 Pandas 库\n",
    "```python\n",
    "import pandas as pd\n",
    "```\n",
    "- **Pandas** 是一个用于数据分析和处理的库。\n",
    "- `pd` 是它的缩写，常用于简化调用。\n",
    "- 主要用于操作数据表（如 Excel 表格），支持创建、读取、操作、清洗和分析数据。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 导入 NumPy 库\n",
    "```python\n",
    "import numpy as np\n",
    "```\n",
    "- **NumPy** 是一个用于科学计算的库。\n",
    "- `np` 是它的缩写。\n",
    "- 提供多维数组支持和大量的数学函数，例如随机数生成、线性代数、统计运算等。\n",
    "- 常与 Pandas 结合使用，以实现高效的数据处理。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 导入 `accuracy_score` 函数\n",
    "```python\n",
    "from sklearn.metrics import accuracy_score\n",
    "```\n",
    "- 从 **scikit-learn** 中的 `metrics` 模块导入了 `accuracy_score` 函数。\n",
    "- 用于评估分类模型的准确率，计算公式为：\n",
    "  \\[\n",
    "  \\text{Accuracy} = \\frac{\\text{正确分类的样本数}}{\\text{总样本数}}\n",
    "  \\]\n",
    "- 通常用在分类问题的模型评估中。\n",
    "\n",
    "---\n",
    "\n",
    "### 4. 导入 Matplotlib 库\n",
    "```python\n",
    "import matplotlib as mpl\n",
    "```\n",
    "- **Matplotlib** 是一个 Python 的绘图库，主要用于生成二维图形。\n",
    "- `mpl` 是缩写，通常用来访问 Matplotlib 的配置选项，例如图形样式、字体设置等。\n",
    "\n",
    "---\n",
    "\n",
    "### 5. 导入 Matplotlib 的子模块 `pyplot`\n",
    "```python\n",
    "import matplotlib.pyplot as plt\n",
    "```\n",
    "- `pyplot` 是 Matplotlib 的一个子模块，提供了一系列用于绘图的函数。\n",
    "- `plt` 是缩写。\n",
    "- 它类似于 MATLAB 的绘图功能，支持生成各种图表（如折线图、柱状图、散点图等）。\n",
    "\n",
    "---\n",
    "\n",
    "### 6. 导入 Seaborn 库\n",
    "```python\n",
    "import seaborn as sns\n",
    "```\n",
    "- **Seaborn** 是一个基于 Matplotlib 的高级可视化库。\n",
    "- 它提供了更加美观和简洁的绘图接口，适合进行统计数据可视化。\n",
    "- 常用于绘制热力图、分布图、成对关系图等，默认主题也比 Matplotlib 更加吸引人。\n",
    "\n",
    "---\n",
    "\n",
    "### 总结\n",
    "这段代码导入了多个用于数据处理、模型评估和可视化的库：\n",
    "- **Pandas** 和 **NumPy**：处理数据。\n",
    "- **scikit-learn**：评估分类模型。\n",
    "- **Matplotlib** 和 **Seaborn**：可视化数据。\n",
    "\n"
   ],
   "id": "d7cce8b8e9092464"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.2 构建数据集路径并读取鸢尾花数据",
   "id": "9caa45db0ee5b4c3"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:43.122384Z",
     "start_time": "2024-12-04T14:32:43.098734Z"
    }
   },
   "cell_type": "code",
   "source": [
    "feat_names = ['sepal-length', 'sepal-width','petal-length', 'petal-width','class']\n",
    "dpath = \"./data/\"\n",
    "df = pd.read_csv(dpath+\"iris1.csv\",names = feat_names,header = None)\n"
   ],
   "id": "743a55d687fde83f",
   "outputs": [],
   "execution_count": 14
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码的作用是读取一个名为 `iris.csv` 的数据文件，并为其列命名。以下是逐行解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. 定义特征名称列表\n",
    "```python\n",
    "feat_names = ['sepal-length', 'sepal-width','petal-length', 'petal-width','class']\n",
    "```\n",
    "- **`feat_names`** 是一个列表，包含了数据集的列名：\n",
    "  1. `sepal-length`：花萼的长度。\n",
    "  2. `sepal-width`：花萼的宽度。\n",
    "  3. `petal-length`：花瓣的长度。\n",
    "  4. `petal-width`：花瓣的宽度。\n",
    "  5. `class`：花的类别。\n",
    "- 这是典型的 **Iris 数据集** 的特征和标签名称。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 定义文件路径\n",
    "```python\n",
    "dpath = \"./data\"\n",
    "```\n",
    "- **`dpath`** 指定了数据文件所在的路径。\n",
    "- 这里路径设置为 `./data`，表示当前代码运行目录下的 `data` 文件夹。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 读取 CSV 文件\n",
    "```python\n",
    "df = pd.read_csv(dpath+\"iris.csv\",names = feat_names,header = None)\n",
    "```\n",
    "- **`pd.read_csv()`** 是 Pandas 中用于读取 CSV 文件的函数。\n",
    "- 参数解释：\n",
    "  1. **`dpath+\"iris.csv\"`**：构造了完整的文件路径，指向 `data` 文件夹中的 `iris.csv` 文件。\n",
    "  2. **`names=feat_names`**：为 CSV 文件的列指定名称，使用上面定义的 `feat_names` 列表。\n",
    "  3. **`header=None`**：表示文件中没有表头（第一行不是列名），否则 Pandas 会将第一行自动识别为表头。\n",
    "- **`df`** 是一个 Pandas 的 DataFrame，用于存储读取的表格数据。\n",
    "\n",
    "---\n",
    "\n",
    "### 最终效果\n",
    "- **读取后的 DataFrame `df`**：表格包含 5 列数据，列名为 `['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'class']`。\n",
    "- **典型数据**（示例）：\n",
    "  ```plaintext\n",
    "     sepal-length  sepal-width  petal-length  petal-width        class\n",
    "  0           5.1          3.5           1.4          0.2  Iris-setosa\n",
    "  1           4.9          3.0           1.4          0.2  Iris-setosa\n",
    "  2           4.7          3.2           1.3          0.2  Iris-setosa\n",
    "  ```\n",
    "  \n"
   ],
   "id": "cdbe0ddd9eb00992"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.3 查看不同类别下特征的直方图，初步了解特征的可分性",
   "id": "589ca4c8e6eb1579"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:32:44.527019Z",
     "start_time": "2024-12-04T14:32:43.156969Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 提取唯一的类别\n",
    "unique_Class = df['class'].unique()\n",
    "\n",
    "# 设置颜色\n",
    "colors = ['blue', 'red', 'green']\n",
    "\n",
    "# 绘制直方图\n",
    "for feature in range(df.shape[1] - 1):  # 遍历特征列\n",
    "    plt.subplot(2, 2, feature + 1)  # 创建子图（2x2 网格）\n",
    "    \n",
    "    # 绘制每个类别的直方图\n",
    "    for label, color in zip(unique_Class, colors):\n",
    "        feat_name = df.columns[feature]  # 当前特征的列名\n",
    "        samples = df[df['class'] == label][feat_name]  # 筛选出该类别的样本\n",
    "        plt.hist(\n",
    "            samples, \n",
    "            label=label, \n",
    "            color=color, \n",
    "            alpha=0.7\n",
    "        )\n",
    "    \n",
    "    plt.xlabel(df.columns[feature])  # 添加 x 轴标签\n",
    "    plt.legend()  # 显示图例\n",
    "\n",
    "plt.tight_layout()  # 调整布局\n",
    "plt.show()\n"
   ],
   "id": "cc0bc7675d0c2171",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 4 Axes>"
      ],
      "image/png": "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wIGyKnoentbl448/1nr27KndcMMN2gMPPKDt3LmzrIruUkJCgjZq1CitVatW2q233qotW7bMeYxVpM/Fk3qU988k28SJE51j2506dUpr3LhxrnH4Nm/erPXs2VO78cYbtcGDB2snT54sq6IWqqC62O12bdmyZVqXLl20G264QRswYECu8UndoWhaFZzHSgghhBCiipHLu0IIIYQQVYAEfUIIIYQQVYAEfUIIIYQQVYAEfUIIIYQQVYAEfUIIIYQQVYAEfUIIIYQQVYAEfUIIIYQQVYAEfUIIIYQQVYAEfaJCOX36NE2aNOH06dMu39+wYQPdunUrlbKcOnWKLVu2uFUuIYRwxVttR2Ft36RJk5g0aRLgmA/4vffec/meqNwk6BOiiJ5//nn2799f1sUQQgjuuusuPvnkE7fS7tq1i5deeqmESyTKI31ZF0AIIYQQxePj44OPj49baWX21apLzvSJYlmzZg1du3alRYsW9OnTh99++w2Af/75h4EDB3LjjTfSq1evXJcS3njjDZ599lkmT55MTEwMvXr14vvvv3e+n5iYyJgxY7j55pu54YYbeOCBB9i9e3eRyldYOcaNG8f06dNp1aoVt9xyC2+//bbzfbvdzmuvvUa7du1o164db775Jj169GDHjh1MmjSJnTt3smTJEgYOHOhc57vvvuP2228nJiaGJ598ktTU1CKVWwhRNspTm3b+/HmaNWvGP//8A4DFYuGmm27i9ddfd6YZN24cCxcuzHN597fffqN3797ceOONPP3002RkZACOy8mDBg0CoEmTJuzYsQOA9PR0nn32WWJiYujSpQubNm0q6i4U5ZgEfaLI/vrrL+bOncv06dP573//S5s2bXjmmWe4fPkyjz/+OK1bt2bjxo1MnDiRN998k88//9y57rfffoumaWzYsIEHH3yQMWPGEBcXB8D48eOx2Wx8+OGHfP7551SvXp0ZM2Z4XL7MzMxCy/HNN99gMpn47LPPGDZsGK+99hrHjh0DYPny5Xz++efMnz+fVatWsXnzZk6dOgXAlClTaNmyJUOHDuWNN95w5vfZZ5+xYMEC1qxZw4EDB3IFkUKI8q28tWmhoaFcf/317Ny5E4A//viDzMxM9uzZAzjO2P3yyy906tQp13opKSk88cQTdOjQgc8//5zrrruOr7/+GoCoqChnm7Vt2zZatmzpLP/111/Pf/7zH+68806ef/550tLSirU/RfkjQZ8osv/9738oikLNmjWJjo7mmWeeYd68eWzcuJHw8HCeeeYZ6tWrR7du3XjyySdZs2aNc93g4GBeeuklGjZsyIgRI2jZsiWffvopmqZx++23M23aNBo2bMh1113HgAEDnI2nJzZt2lRoOUJCQpg4cSJ169Zl+PDhhISE8OeffwLw/vvv88wzz9CxY0eaN2/Oq6++6rwsEhgYiMFgwM/Pj5CQEGd+EyZM4MYbbyQmJoY777yTgwcPFnHvCiFKW3ls02699VZn0Pfbb79x2223sW/fPmw2G4cOHcJsNnPTTTflWue///0vYWFhTJgwgQYNGjB69GhatGgBgE6nIzg4GIDIyEiMRiMALVu2ZPjw4dSuXZunnnoKs9nM0aNHi7tLRTkj9/SJIuvYsSONGzfm3nvvpXnz5nTv3p1+/frx008/cfDgQecvSACbzYZOp3O+vuGGG5yNTfbrI0eOoCgKjzzyCF999RV79uzh2LFj/Pnnn9jt9jzb37hxI9OnT3e+fvHFF3O9f/To0ULLER0dneu1v78/VquVlJQUzp4962woARo0aOBsLPNTp04d5/8DAwPJysoqML0Qovwoj21ap06d+Pjjj9E0jV27dvHggw+yb98+/v77b3bu3EmHDh3Q63N35XFxcTRt2hRFUZzLWrRo4bzE60rt2rWd/w8MDASQ9qsSkqBPFJmvry/r169n586d/Pjjj2zYsIEPPviArl27csstt/DCCy/ku+61jZTNZkNVVex2O0OHDuXixYvcdddddOvWDYvFQmxsbJ48unXrRkxMjPN1eHg4//d//+d8bbVaCy2HwWDIs0zTNGf5rr3hubAboFVVTp4LUVGVxzbNx8eHrKwsDh06xJ49e5g9ezatWrViz549/PLLL/Ts2dNlea5tqwwGQ4FBX84ANr88RMUnPZQost9//53ly5fTvn17Jk+ezNdff01WVhY1atTg2LFjREdHU7duXerWrcvevXtZu3atc91Dhw7l+qX7559/0qRJE+Li4ti1axerV6/mySefpEuXLpw9exbI2wAFBAQ4869bty4BAQG53q9fv36h5chPUFAQ1apV48CBA85lp06d4uLFi0XaV0KI8q88tml6vZ727dvz3nvvERERQUREBG3atOGXX35h165dee7nA2jUqBF//fUXNpvNuezvv/92/j/nGUBRtUjQJ4rMx8eHpUuXsn79ek6fPs2XX37J5cuX6dGjB5mZmbzwwgscOXKELVu28MorrxAeHu5c99SpU8ybN4+jR4+ybNkyDhw4QN++fQkKCkJVVb788kv+97//8fXXXztvOjabzR6V77777iu0HAUZOHAgr7/+Or/88gsHDx5k8uTJwNUG08/Pj+PHj3Pu3DmPyiWEKJ/Ka5t266238tlnn9GqVSsA2rRpw48//kh0dDQ1atTIk/7uu+8mIyODV155haNHj/LOO+/kelrY19cXcASmcgm3apGgTxRZs2bNeOWVV3jnnXe48847eeutt5g3bx5NmjTh7bff5vjx4/Tu3ZupU6cyYMAAnnjiCee6MTExpKSk0Lt3b/773/+yYsUKateuTY0aNZgxYwZvv/0299xzDytWrGDq1Kno9Xr++usvj8oXEBBQaDkKMnToUHr06MHo0aMZPHgwXbt2RVEU5yXhfv36sXXrVoYPH+5RuYQQ5VN5bdM6deqExWKhdevWADRv3hwfHx+XZ/nA8VDJO++8wx9//MH999/Pzz//zP333+98v0mTJtx66608/PDDzlmFRNWgaHLRXpSyN954g507d7p1mbUs/fTTT9xwww2EhYUBjmEQbrnlFr7//nuio6PLuHRCiPKiorRpQsiDHELk46OPPuL9999n/PjxKIrC4sWLadGihQR8QgghKiS5vCtEPl544QVUVeXhhx/moYcewm63s3Tp0rIulhBCCFEkcnlXCCGEEKIKkDN9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgAR9QgghhBBVgL6sC1Bc586loWllXQrvUBQIDw+sVHUqC7IfvaMy7MfsOlQEKSlphIVV7P0NleO4gcpTD6g8daks9QDP6+KttqzCB32aRoX/8K9VGetUFmQ/eofsx9KRvY8ry/6WepQ/laUulaUeUPp1kcu7QgghhBBVgAR9QgghhBBVgAR9QgghhBBVQIW/p68gmqZht9uw2+1lXRS3KApkZmZisZgrzf0KZeHa/ajT6VFV+X0jhCif7HY7Npu1xPKvLH1L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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 15
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "以下是这段代码逐行的详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. 提取唯一的类别\n",
    "```python\n",
    "unique_Class = df['class'].unique()\n",
    "```\n",
    "- **作用**：\n",
    "  - 从数据集 `df` 的 `class` 列中提取所有唯一类别值。\n",
    "  - `unique()` 方法返回一个包含非重复值的数组。\n",
    "- **目的**：\n",
    "  - 提供一个列表，列出数据集中所有的分类标签（如 `['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']`），用于绘制分类直方图。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 设置颜色\n",
    "```python\n",
    "colors = ['blue', 'red', 'green']\n",
    "```\n",
    "- **作用**：\n",
    "  - 定义每个类别对应的颜色。\n",
    "  - 此处分别将 `blue`、`red` 和 `green` 作为类别直方图的颜色。\n",
    "- **目的**：\n",
    "  - 使用不同颜色区分每个类别的直方图，便于观察。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 遍历特征列\n",
    "```python\n",
    "for feature in range(df.shape[1] - 1):  # 遍历特征列\n",
    "```\n",
    "- **`df.shape[1]`**：\n",
    "  - 获取 DataFrame 的列数。\n",
    "- **`range(df.shape[1] - 1)`**：\n",
    "  - 遍历前 `n-1` 列，忽略最后一列（`class` 列），因为最后一列是分类标签。\n",
    "- **`feature`**：\n",
    "  - 迭代变量，表示当前特征列的索引。\n",
    "- **目的**：\n",
    "  - 遍历所有数值特征，为每个特征绘制单独的子图。\n",
    "\n",
    "---\n",
    "\n",
    "### 4. 创建子图\n",
    "```python\n",
    "plt.subplot(2, 2, feature + 1)  # 创建子图（2x2 网格）\n",
    "```\n",
    "- **`plt.subplot(2, 2, feature + 1)`**：\n",
    "  - 将绘图区分为 2 行 2 列的网格。\n",
    "  - `feature + 1` 确定当前子图的位置。\n",
    "    - 例如，第 1 个特征在第 1 个子图（左上角），第 2 个特征在第 2 个子图（右上角）。\n",
    "- **目的**：\n",
    "  - 为每个特征创建一个单独的绘图区，直方图会分别显示。\n",
    "\n",
    "---\n",
    "\n",
    "### 5. 遍历类别并绘制直方图\n",
    "```python\n",
    "for label, color in zip(unique_Class, colors):\n",
    "```\n",
    "- **`zip(unique_Class, colors)`**：\n",
    "  - 将类别 `unique_Class` 和颜色 `colors` 配对。\n",
    "  - 每次迭代分别返回一个类别（`label`）和对应的颜色（`color`）。\n",
    "- **目的**：\n",
    "  - 为每个类别分别绘制直方图，并为其分配颜色。\n",
    "\n",
    "---\n",
    "\n",
    "### 6. 筛选出当前类别的样本\n",
    "```python\n",
    "feat_name = df.columns[feature]  # 当前特征的列名\n",
    "samples = df[df['class'] == label][feat_name]  # 筛选出该类别的样本\n",
    "```\n",
    "- **`df.columns[feature]`**：\n",
    "  - 获取当前特征的列名。\n",
    "  - 例如，`feature=0` 时，`feat_name='sepal-length'`。\n",
    "- **`df[df['class'] == label][feat_name]`**：\n",
    "  - 筛选出 `class` 列等于当前 `label` 的样本。\n",
    "  - 提取该类别样本在当前特征列（`feat_name`）上的值。\n",
    "- **目的**：\n",
    "  - 获取属于当前类别的数据，用于绘制直方图。\n",
    "\n",
    "---\n",
    "\n",
    "### 7. 绘制直方图\n",
    "```python\n",
    "plt.hist(\n",
    "    samples, \n",
    "    label=label, \n",
    "    color=color, \n",
    "    alpha=0.7\n",
    ")\n",
    "```\n",
    "- **`plt.hist(samples)`**：\n",
    "  - 绘制 `samples` 数据的直方图。\n",
    "- **参数**：\n",
    "  - `label=label`：设置图例中的标签，表示当前类别名称。\n",
    "  - `color=color`：指定直方图的颜色。\n",
    "  - `alpha=0.7`：设置透明度，避免多个直方图重叠后看不清。\n",
    "- **目的**：\n",
    "  - 显示当前特征在不同类别中的分布情况。\n",
    "\n",
    "---\n",
    "\n",
    "### 8. 设置 x 轴标签\n",
    "```python\n",
    "plt.xlabel(df.columns[feature])  # 添加 x 轴标签\n",
    "```\n",
    "- 为 x 轴添加当前特征的名称，便于读者理解。\n",
    "\n",
    "---\n",
    "\n",
    "### 9. 显示图例\n",
    "```python\n",
    "plt.legend()  # 显示图例\n",
    "```\n",
    "- 显示每个类别对应的图例标签，标识颜色与类别的对应关系。\n",
    "\n",
    "---\n",
    "\n",
    "### 10. 调整布局\n",
    "```python\n",
    "plt.tight_layout()  # 调整布局\n",
    "```\n",
    "- 自动调整子图之间的间距，避免标题或轴标签重叠。\n",
    "\n",
    "---\n",
    "\n",
    "### 11. 显示绘图\n",
    "```python\n",
    "plt.show()\n",
    "```\n",
    "- 显示生成的所有子图。\n",
    "\n",
    "---\n",
    "\n",
    "### 结果\n",
    "- 每个子图展示一个特征的直方图，区分不同类别的数据分布。\n",
    "- 例如：\n",
    "  - 第一个子图显示 `sepal-length` 在 `Iris-setosa`、`Iris-versicolor` 和 `Iris-virginica` 中的分布。\n"
   ],
   "id": "b649128f967c140"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.4 完成数据标准化，包含数据标准化的构建、训练和变换三部分",
   "id": "d2408911b02e909"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:34:07.828317Z",
     "start_time": "2024-12-04T14:34:07.813313Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "X = df.iloc[:,0:2]\n",
    "y = df['class']\n",
    "\n",
    "# 构建StandardScaler()类\n",
    "scaler = StandardScaler()\n",
    "# 使用fit方法，计算训练集的均值和标准差\n",
    "scaler.fit(X)\n",
    "\n",
    "# 使用transform方法，进行标准化变换，将特征数据的均值调整为0，方差调整为1\n",
    "X_scaled= scaler.transform(X)\n"
   ],
   "id": "6620ae68d27e7e5a",
   "outputs": [],
   "execution_count": 20
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码的功能是对特征数据 `X` 进行标准化（均值为 0，方差为 1），以便后续的机器学习模型能够更好地处理具有不同量纲或分布的特征数据。以下是逐行详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. 导入 `StandardScaler`\n",
    "```python\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "```\n",
    "- **作用**：\n",
    "  - 导入 `StandardScaler` 类，用于对数据进行标准化。\n",
    "- **标准化的含义**：\n",
    "  - 将数据的均值调整为 0，标准差调整为 1，使特征具有相同的量纲和分布。\n",
    "  - 公式为：\n",
    "    \\[\n",
    "    X_{\\text{scaled}} = \\frac{X - \\mu}{\\sigma}\n",
    "    \\]\n",
    "    其中，\\(\\mu\\) 是特征均值，\\(\\sigma\\) 是标准差。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 分割特征与目标变量\n",
    "```python\n",
    "X = df.iloc[:, 0:2]  # 提取前两列作为特征\n",
    "y = df['Class']      # 提取类别列作为目标变量\n",
    "```\n",
    "- **`X = df.iloc[:, 0:2]`**：\n",
    "  - 使用 `iloc` 提取 `df` 的第 0 列和第 1 列（不包括 `class` 列）。\n",
    "  - 作为特征矩阵，通常用于模型训练。\n",
    "- **`y = df['Class']`**：\n",
    "  - 提取 `Class` 列作为目标变量，用于分类任务。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 构建 `StandardScaler` 对象\n",
    "```python\n",
    "scaler = StandardScaler()\n",
    "```\n",
    "- **`scaler`**：\n",
    "  - 创建 `StandardScaler` 类的实例。\n",
    "  - 它包含了对数据进行标准化的功能。\n",
    "\n",
    "---\n",
    "\n",
    "### 4. 计算训练集的均值和标准差\n",
    "```python\n",
    "scaler.fit(X)\n",
    "```\n",
    "- **`fit(X)`**：\n",
    "  - 计算并存储 `X` 每一列的均值（`mean_` 属性）和标准差（`scale_` 属性）。\n",
    "- **作用**：\n",
    "  - 准备好将特征数据转换为标准正态分布。\n",
    "\n",
    "---\n",
    "\n",
    "### 5. 对数据进行标准化\n",
    "```python\n",
    "X_scaled = scaler.transform(X)\n",
    "```\n",
    "- **`transform(X)`**：\n",
    "  - 对特征矩阵 `X` 中的每列应用标准化变换：\n",
    "    \\[\n",
    "    X_{\\text{scaled}} = \\frac{X - \\mu}{\\sigma}\n",
    "    \\]\n",
    "    其中，\\(\\mu\\) 和 \\(\\sigma\\) 是 `fit` 方法计算得到的均值和标准差。\n",
    "- **`X_scaled`**：\n",
    "  - 是标准化后的特征矩阵，均值为 0，标准差为 1。\n",
    "- **作用**：\n",
    "  - 提高模型训练的稳定性和性能，避免特征值量纲差异对结果的影响。\n",
    "\n",
    "---\n",
    "\n",
    "### 整体流程\n",
    "1. 创建 `StandardScaler` 类的对象。\n",
    "2. 使用 `fit` 方法计算特征数据的均值和标准差。\n",
    "3. 使用 `transform` 方法将原始数据转换为标准化数据。\n",
    "4. 结果 `X_scaled` 可直接用于机器学习模型。\n",
    "\n",
    "如需进一步可视化或分析，请随时提问！"
   ],
   "id": "a5c30dc35a83819e"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.5完成数据训练集与测试集分割，分割比例二八分，包括导入部分与分割部分",
   "id": "a8c2dd673010e825"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:34:15.085447Z",
     "start_time": "2024-12-04T14:34:15.072332Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "X_train,X_test,y_train,y_test = train_test_split(X,y,test_size = 0.2,random_state= 42)"
   ],
   "id": "5e3c478a83f0d646",
   "outputs": [],
   "execution_count": 21
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码的功能是将数据集 `X` 和 `y` 按一定比例随机分割为训练集和测试集，以下是逐行解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. 导入 `train_test_split`\n",
    "```python\n",
    "from sklearn.model_selection import train_test_split\n",
    "```\n",
    "- **作用**：\n",
    "  - 从 `scikit-learn` 中导入 `train_test_split` 方法，用于将数据集划分为训练集和测试集。\n",
    "- **为什么需要划分数据集？**\n",
    "  - **训练集** 用于训练模型。\n",
    "  - **测试集** 用于评估模型性能，确保模型能够泛化到未见过的数据。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 数据集划分\n",
    "```python\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)\n",
    "```\n",
    "- **作用**：\n",
    "  - 按照 `test_size=0.2` 的比例，将特征矩阵 `X` 和目标变量 `y` 随机划分为训练集和测试集。\n",
    "  - 返回的四个部分是：\n",
    "    - `X_train`：训练集的特征矩阵。\n",
    "    - `X_test`：测试集的特征矩阵。\n",
    "    - `y_train`：训练集的目标变量。\n",
    "    - `y_test`：测试集的目标变量。\n",
    "\n",
    "#### 参数说明：\n",
    "1. **`X` 和 `y`**：\n",
    "   - 分别是特征矩阵和目标变量。\n",
    "   - 代码中：\n",
    "     - `X` 是特征数据。\n",
    "     - `y` 是分类标签数据。\n",
    "\n",
    "2. **`test_size=0.2`**：\n",
    "   - 表示测试集占总数据集的 20%。\n",
    "   - 剩下的 80% 分配给训练集。\n",
    "\n",
    "3. **`random_state=42`**：\n",
    "   - 控制随机数生成的种子，确保数据划分的可重复性。\n",
    "   - 如果不设置该参数，每次划分的数据集可能不同。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 结果\n",
    "- 数据被分成：\n",
    "  - **训练集**：\n",
    "    - `X_train`：训练集特征数据，占总数据的 80%。\n",
    "    - `y_train`：训练集目标变量。\n",
    "  - **测试集**：\n",
    "    - `X_test`：测试集特征数据，占总数据的 20%。\n",
    "    - `y_test`：测试集目标变量。\n",
    "\n",
    "---\n",
    "\n",
    "### 示例情景\n",
    "如果数据集大小为 100 行：\n",
    "- 训练集：80 行。\n",
    "  - 特征：`X_train`。\n",
    "  - 目标：`y_train`。\n",
    "- 测试集：20 行。\n",
    "  - 特征：`X_test`。\n",
    "  - 目标：`y_test`。\n",
    "\n",
    "---\n",
    "\n",
    "### 使用目的\n",
    "1. 训练集用于模型训练，模型会“学习”数据的规律。\n",
    "2. 测试集用于评估模型性能，检查其在新数据上的表现。\n",
    "3. 确保模型不仅对训练数据有较好的拟合能力，还具有良好的泛化能力。\n",
    "\n",
    "如果有更多问题或需要进一步解释，请随时问我！"
   ],
   "id": "2ca109f701da75aa"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 2.6 己知以下部分代码，实现逻辑回归模型的交叉验证下的超参数调优，折数为10折，损失函数为负log损失。",
   "id": "24061566f129004d"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2024-12-04T14:34:21.163018Z",
     "start_time": "2024-12-04T14:34:18.741851Z"
    }
   },
   "cell_type": "code",
   "source": [
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "Cs = [ 0.1, 1, 10, 100, 1000]\n",
    "tuned_parameters = dict(C = Cs)\n",
    "lr = LogisticRegression()\n",
    "grid=GridSearchCV(lr,tuned_parameters,cv=10, scoring='neg_log_loss',n_jobs = 4)\n",
    "grid.fit(X_train, y_train)\n",
    "lr_best = grid.best_estimator_"
   ],
   "id": "f9bc6cee3113e28c",
   "outputs": [],
   "execution_count": 22
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "这段代码的功能是利用网格搜索（`GridSearchCV`）对逻辑回归模型（`LogisticRegression`）的正则化参数 `C` 进行超参数调优，并选择最佳模型。以下是详细解释：\n",
    "\n",
    "---\n",
    "\n",
    "### 1. 导入 `GridSearchCV` 和 `LogisticRegression`\n",
    "```python\n",
    "from sklearn.model_selection import GridSearchCV\n",
    "from sklearn.linear_model import LogisticRegression\n",
    "```\n",
    "- **`GridSearchCV`**：\n",
    "  - 用于超参数调优，通过指定的参数网格自动进行交叉验证，找到最优参数组合。\n",
    "- **`LogisticRegression`**：\n",
    "  - 逻辑回归模型，用于分类任务。\n",
    "  - 参数 `C` 控制正则化的强度。\n",
    "\n",
    "---\n",
    "\n",
    "### 2. 定义参数网格\n",
    "```python\n",
    "Cs = [0.1, 1, 10, 100, 1000]  # 候选参数\n",
    "tuned_parameters = dict(C=Cs)  # 转换为字典形式\n",
    "```\n",
    "- **`Cs`**：\n",
    "  - 逻辑回归的正则化参数候选值列表。\n",
    "  - `C` 值越小，正则化越强；`C` 值越大，正则化越弱。\n",
    "- **`tuned_parameters`**：\n",
    "  - 参数网格，键是模型的超参数名称（`C`），值是候选值列表。\n",
    "\n",
    "---\n",
    "\n",
    "### 3. 初始化逻辑回归模型\n",
    "```python\n",
    "lr = LogisticRegression()\n",
    "```\n",
    "- **`lr`**：\n",
    "  - 创建逻辑回归模型实例。\n",
    "\n",
    "---\n",
    "\n",
    "### 4. 初始化 `GridSearchCV`\n",
    "```python\n",
    "grid = GridSearchCV(lr, tuned_parameters, cv=10, scoring='neg_log_loss', n_jobs=4)\n",
    "```\n",
    "- **参数说明**：\n",
    "  1. **`lr`**：\n",
    "     - 需要调优的模型实例。\n",
    "  2. **`tuned_parameters`**：\n",
    "     - 定义的参数网格。\n",
    "  3. **`cv=10`**：\n",
    "     - 进行 10 折交叉验证，保证模型评估的稳定性。\n",
    "  4. **`scoring='neg_log_loss'`**：\n",
    "     - 使用负对数损失（log loss）作为模型评估指标。\n",
    "     - 对数损失越小，模型性能越好。\n",
    "  5. **`n_jobs=4`**：\n",
    "     - 使用 4 个 CPU 核心并行执行搜索任务，提高效率。\n",
    "\n",
    "---\n",
    "\n",
    "### 5. 进行网格搜索\n",
    "```python\n",
    "grid.fit(X_train, y_train)\n",
    "```\n",
    "- **作用**：\n",
    "  - 在训练集 `X_train` 和 `y_train` 上执行网格搜索，评估每种 `C` 值对应的模型性能。\n",
    "  - 找到在交叉验证中表现最好的参数值。\n",
    "- **内部过程**：\n",
    "  - 对每个参数 `C`：\n",
    "    - 执行 10 折交叉验证。\n",
    "    - 计算每折的对数损失，并取平均值。\n",
    "\n",
    "---\n",
    "\n",
    "### 6. 获取最佳模型\n",
    "```python\n",
    "lr_best = grid.best_estimator_\n",
    "```\n",
    "- **`grid.best_estimator_`**：\n",
    "  - 根据交叉验证的结果，返回具有最优 `C` 值的逻辑回归模型实例。\n",
    "- **`lr_best`**：\n",
    "  - 经过调优的最佳逻辑回归模型，可直接用于预测和进一步分析。\n",
    "\n",
    "---\n",
    "\n",
    "### 总结\n",
    "这段代码的主要步骤：\n",
    "1. 定义参数网格（正则化参数 `C`）。\n",
    "2. 利用 `GridSearchCV` 进行网格搜索和交叉验证。\n",
    "3. 找到最佳参数，并返回对应的逻辑回归模型。\n",
    "\n",
    "### 使用场景\n",
    "- **超参数调优**：提高模型性能。\n",
    "- **交叉验证**：确保参数选择的可靠性。\n",
    "- **模型部署**：使用最佳模型进行预测。\n",
    "\n",
    "如需更深入的代码分析或扩展示例，请告诉我！\n"
   ],
   "id": "fc3da52d917e2433"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
